﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.Net.Http.Headers;
using 模型绑定.Models;

namespace 模型绑定.Controllers
{
    [Route("[controller]")]
    public class ModelBindController : Controller
    {
        /// <summary>
        /// BindProperty特性
	    ///【1】如果要绑定控制器里面的属性，这个时候我们可以通过BindProperty特性标识属性（针对表单POST的请求），
	    ///	如果是GET请求需要设置参数SupportsGet为true。
	    ///【2】针对[FromBody] 特性进行标识的请求，在控制器上的属性通过BindProperty特性进行标识，绑定无效。
        /// </summary>
        [BindProperty(SupportsGet = true)]
        public string A { get; set; }


        //访问:/Employees
        [HttpGet("Employees")]
        public IActionResult Index()
        {
            return View();
        }


        //[HttpPost("Employees")]
        //public IActionResult Index(Employee employee)
        //{
        //    if (!ModelState.IsValid)
        //    {
        //        return View();
        //    }

        //    return View();
        //}


        //[HttpPost("Employees")]
        //public IActionResult Index([Bind("EmployeeName")]Employee employee)  //仅模型绑定EmployeeName
        //{
        //    if (!ModelState.IsValid)
        //    {
        //        return View();
        //    }

        //    return View();
        //}


        [HttpPost("Employees")]
        public IActionResult Index([FromBody, Bind("EmployeeName")]Employee employee) //如果通过[FromBody]进行标识，无论是类还是控制器Action方法上面，通过Bind特性进行标识无效。
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            return Ok();
        }




        [HttpGet("Employees/Details")]
        public IActionResult Details()
        {
            Employee employee = new Employee()
            {
                Address = "浙江金华",
                BirthDate = DateTime.Now,
                Email = "aaa@qq.com",
                EmployeeName = "张三",
                Id = 1,
                Phone = "15866778899",
                Salary = 200
            };

            return View(employee);
        }


        /*
            PostMan提交,不提供id这个键,返回提示,id参数未提供.
            url后加上?id=,如:http://localhost:58478/ModelBind/test?id,则返回状态码200.
            [BindRequired]:只关心是否有键,不关心是否有值或者值是否为空.
            {
                "id": [
                    "A value for the 'id' parameter or property was not provided."
                ]
            } 
        */
        [HttpGet("test")]
        public IActionResult Get([BindRequired]string id)
        {
            //http://localhost:58478/ModelBind/test?A=100
            var a = A;

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            return Ok();
        }


        //PostMan请求地址:http://localhost:58478/ModelBind/bind-source/1   返回结果为:1
        //请求地址:http://localhost:58478/ModelBind/bind-source/1?id=2 返回结果为:1
        [HttpGet("bind-source/{id:int}")] //路由参数id,必须为int
        public IActionResult BindSourceExample(int id)
        {
            return Ok(id);
        }

        //PostMan请求地址:http://localhost:58478/ModelBind/bind-source/1   返回结果为:1
        //请求地址:http://localhost:58478/ModelBind/bind-source/1?id=2 返回结果为:1
        [HttpGet("bind-source2/{id:int}")]
        public IActionResult BindSourceExample2([FromRoute]int id)  //强制路由绑定
        {
            return Ok(id);
        }


        //PostMan请求地址:http://localhost:58478/ModelBind/bind-source/1   返回结果为:0 (因为强行url查询字符串绑定,所以没绑定成功,结果为0)
        //请求地址:http://localhost:58478/ModelBind/bind-source/1?id=2 返回结果为:2
        [HttpGet("bind-source3/{id:int}")]
        public IActionResult BindSourceExample3([FromQuery]int id)  //强制url传参绑定
        {
            return Ok(id);
        }


        [HttpGet("bind-source4")]
        public IActionResult BindSourceExample4([FromHeader(Name = "Accept-Language")]string language)
        {
            return Ok(language);
        }

    }
}